﻿//#define DEBUG_MY
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.IO;
using AnalysisSystemLog.Define.Utility;

/** TODO: 新增功能 
 * 1. 搜索日志ID4624，并根据LoginType参数判断是否存在他人登录 
 * 2. 区分本地计算机和远程服务器类别的不同。识别出登录window服务器的所有用户与状态
 */
namespace AnalysisSystemLog
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            // 过渡界面所用线程 2020.02.19 wj
            Thread threadOfWatting = new Thread(new ThreadStart(TheadOfWaittingFunc))
            {
                IsBackground = true	//默认为前台线程
            };
            threadOfWatting.Start();

#if  !DEBUG_MY
            ShowEventLogToListView();
#endif
            SystemTimer.Start();
            waitForm.Dispose();
            threadOfWatting.Abort();
            // 界面置于最前 
            this.TopMost = true;
        }

        private FormWaitting waitForm = new FormWaitting();
        private void TheadOfWaittingFunc()
        {
            waitForm = new FormWaitting();
            waitForm.ShowDialog();
            waitForm.BackColor = Color.Transparent;
        }


        /**
          * \brief 将合并后的list写入文件
          */
        private void WriteListRecordsToFile()
        {
            FileStream fs = new FileStream(strFilePath, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            foreach (var v in listStructOfWriteToFile)
            {
                sw.WriteLine(encodeString(LogRecord.ConvertRecordToString(v)));
            }
            sw.Close();
        }

        /**
          * \brief 从文件中读取数据到list中
          */
        private void ReadListFromFile()
        {
            FileStream fs = new FileStream(strFilePath, FileMode.OpenOrCreate, FileAccess.Read);
            StreamReader sr = new StreamReader(fs);
            string str;
            while ((str = sr.ReadLine()) != null)
            {
                str = encodeString(str);
                listStructOfFile.Add(LogRecord.ConvertStringToRecord(str));
            }
            sr.Close();
        }

        string strKey = "EventLogCSharp";
        string encodeString(string str)
        {
            //StringBuilder sb = new StringBuilder(str);
            //for (int i = 0; i < sb.Length; i++)
            //{
            //    sb[i] ^= strKey[i % strKey.Length];
            //}
            //return sb.ToString();
            return str;
        }

        /// <summary>
        /// 将listview中的记录读取到list中
        /// </summary>
        private void AddListViewToList()
        {
            foreach (var v in listViewShow.Items)
            {
                ListViewItem lvi;
                if ((lvi = v as ListViewItem) != null)
                {
                    LogRecord s = new LogRecord();
                    s.InnerID = !string.IsNullOrEmpty(lvi.SubItems[0].Text) ? lvi.SubItems[0].Text : "";
                    s.GeneratedTime = !string.IsNullOrEmpty(lvi.SubItems[1].Text) ? lvi.SubItems[1].Text : "";
                    s.DayWeek = !string.IsNullOrEmpty(lvi.SubItems[2].Text) ? lvi.SubItems[2].Text : "";
                    s.GeneratedDuration = !string.IsNullOrEmpty(lvi.SubItems[3].Text) ? lvi.SubItems[3].Text : "";
                    s.Context = !string.IsNullOrEmpty(lvi.SubItems[4].Text) ? lvi.SubItems[4].Text : "";
                    s.Comment = !string.IsNullOrEmpty(lvi.SubItems[5].Text) ? lvi.SubItems[5].Text : "";
                    listStructOfListView.Add(s);
                }
                else
                {
                    MessageBox.Show("不该出现的错误");
                }
            }
        }


        /**
          * \brief  将备注在listWriteToFile中更新
          *
          * \param list
          * \param lvi
          * \param strComment"></param>
          */
        void addCommentToList(List<LogRecord> list, ListViewItem lvi, string strComment)
        {
            foreach (var v in list)
            {
                if (lvi.SubItems[0].Text.Equals(v.InnerID)
                    && lvi.SubItems[1].Text.Equals(v.GeneratedTime)
                    && lvi.SubItems[2].Text.Equals(v.DayWeek))
                {
                    v.Comment = strComment;
                    break;
                }
            }
        }

        /**
         * \brief  合并listview中的记录和从文件中读取的记录
         */
        private void CombineListViewAndFileList()
        {
            List<LogRecord> list = new List<LogRecord>();
            listStructOfWriteToFile.AddRange(listStructOfFile);

            foreach (var v in listStructOfListView)
            {
                bool bIsExist = false;
                for (int i = 0; i < listStructOfWriteToFile.Count; i++)
                {
                    if (v.InnerID.Equals(listStructOfWriteToFile[i].InnerID) &&
                        v.GeneratedTime.Equals(listStructOfWriteToFile[i].GeneratedTime) &&
                        v.DayWeek.Equals(listStructOfWriteToFile[i].DayWeek))
                    /*v.d_duration.Equals(listStructOfWriteToFile[i].d_duration))
                     * 本字段是跟在关机之后的。当文件中的早期时间有持续时间，而事件日志中对应的持续时间被推掉了此字段就会不匹配。
                     * 如现在是2012-11-12 10:29:50，而9月11的某时刻有关机，有持续时间。但是
                     * 现在事件日志中没有那时刻对应的开机，所以列表中就不会出现关机的持续时间。而文件中有。就不会匹配。
                     */
                    {
                        if (!v.Context.Equals(listStructOfWriteToFile[i].Context))
                        {
                            listStructOfWriteToFile[i].Context = v.Context;
                        }
                        if (!v.Comment.Equals(listStructOfWriteToFile[i].Comment))
                        {
                            v.Comment = listStructOfWriteToFile[i].Comment;
                        }
                        bIsExist = true;
                        break;
                    }
                }
                if (!bIsExist)
                {
                    list.Add(v);
                }
            }
            listStructOfWriteToFile.AddRange(list);
        }

        private void Timer_Show(object sender, EventArgs e)
        {
            if (bIsFirstStart)
            {
                AddListViewToList();
                ReadListFromFile();
                CombineListViewAndFileList();

                ShowDataListToListView(listStructOfWriteToFile);

                bIsFirstStart = false;
                TopMost = false;
            }

            labelRunningTime.Text = WorkTime;
            tsTotal = tsTotal.Add(new TimeSpan(0, 0, 1));
            labelTimeContinue.Text = tsTotal.Seconds == 0 ? "" : (tsTotal.Days.ToString() + "天")
               + tsTotal.Hours.ToString("00") + "小时"
               + tsTotal.Minutes.ToString("00") + "分钟"
               + tsTotal.Seconds.ToString("00") + "秒";

            ShowExceptionPowerTimes();
        }

        //跳转到下一个jtd中表示的（开关机）处
        private void JumpToNext(LogConstant.JumpToDirection jtd)
        {
            if (jtd == LogConstant.JumpToDirection.PowerDown)
            {
                JumpToString(1, new string[] { "非正常关机" });
            }
            else if (jtd == LogConstant.JumpToDirection.PowerOn)
            {
                JumpToString(1, new string[] { "非正常开机" });
            }
            else if (jtd == LogConstant.JumpToDirection.PowerUpAndDown)
            {
                JumpToString(1, new string[] { "非正常开机", "非正常关机" });
            }
        }
        //跳转到上一个jtd中表示的（开关机）处
        private void JumpToUp(LogConstant.JumpToDirection jtd)
        {
            if (jtd == LogConstant.JumpToDirection.PowerDown)
            {
                JumpToString(0, new string[] { "非正常关机" });
            }
            else if (jtd == LogConstant.JumpToDirection.PowerOn)
            {
                JumpToString(0, new string[] { "非正常开机" });
            }
            else if (jtd == LogConstant.JumpToDirection.PowerUpAndDown)
            {
                JumpToString(0, new string[] { "非正常关机", "非正常开机" });
            }
        }

        /// <summary>
        /// 根据JumpDirection来决定在JumpIndex的上还是下查找说明为str的项
        /// </summary>
        /// <param name="str">下一个异常开机...</param>
        /// <param name="jd">方向</param>
        private void JumpToString(int jumpDirection, params string[] str)
        {
            int iItemCount = listViewShow.Items.Count;

            if (jumpDirection == 0)
            {
                JumpIndex = JumpIndex - 1 < 0 ? iItemCount - 1 : JumpIndex - 1;
                int j = 0; //只允许goto一次
            jls:
                int i;
                for (i = JumpIndex; i > 0; i--)
                {
                    if (CompareToStringArray(i, str))
                    {
                        return;
                    }
                }
                if (i == 0 && j != 0)
                {
                    return;
                }
                j++;
                JumpIndex = iItemCount - 1;
                goto jls;
            }
            else if (jumpDirection == 1)
            {
                JumpIndex = JumpIndex + 1 >= iItemCount ? 0 : JumpIndex + 1;
                int j = 0;
            JLS:
                int i;
                for (i = JumpIndex; i < iItemCount; i++)
                {
                    if (CompareToStringArray(i, str))
                    {
                        return;
                    }
                }
                if (i == iItemCount && j != 0)
                {
                    return;
                }
                j++;
                JumpIndex = 0;
                goto JLS;
            }
        }

        //比较listView的i行第5个元素的内容和strArray比较。如果相同，选中并显示。同时显示是第几个异常开关机以及总异常数
        bool CompareToStringArray(int i, string[] strArray)
        {
            if (strArray.Length == 1)
            {
                if (listViewShow.Items[i].SubItems[4].Text.Equals(strArray[0]))
                {
                    listViewShow.Items[i].Selected = true;
                    listViewShow.Items[i].EnsureVisible();
                    JumpIndex = i;
                    //显示当前选择的是第几个异常开机/关机
                    int iSerial = 0;
                    List<int> listTemp = strArray[0].Equals("非正常关机") ? listExcepPowerDown : listExcepPowerOn;

                    if ((iSerial = listTemp.FindIndex(j => j == Convert.ToInt32(listViewShow.Items[i].SubItems[5].Text))) != -1)
                    {
                        lbSerial.Text = (iSerial + 1).ToString() + "/" + listTemp.Count.ToString();
                    }
                    return true;
                }
            }
            else if (strArray.Length == 2)	//下一个非正常开机或者关机
            {
                if (listViewShow.Items[i].SubItems[4].Text.Equals(strArray[0])
                    || listViewShow.Items[i].SubItems[4].Text.Equals(strArray[1]))
                {
                    listViewShow.Items[i].Selected = true;
                    listViewShow.Items[i].EnsureVisible();
                    JumpIndex = i;
                    //显示当前选择的是第几个异常开机/关机
                    int iSerial = 0;
                    List<int> listTemp = listViewShow.Items[i].SubItems[4].Text.Equals("非正常关机") ? listExcepPowerDown : listExcepPowerOn;

                    if ((iSerial = listTemp.FindIndex(j => j == Convert.ToInt32(listViewShow.Items[i].SubItems[5].Text))) != -1)
                    {
                        lbSerial.Text = (iSerial + 1).ToString() + "/" + listTemp.Count.ToString();
                    }
                    return true;
                }
            }
            return false;
        }


        /// <summary>
        /// 保存异常开机的序号
        /// </summary>
        List<int> listExcepPowerOn;
        List<int> listExcepPowerDown;
        //显示异常开关机的次数
        public void ShowExceptionPowerTimes()
        {
            listExcepPowerOn = new List<int>();
            listExcepPowerDown = new List<int>();

            for (int i = 0; i < listViewShow.Items.Count; i++)
            {
                if (listViewShow.Items[i].SubItems[4].Text.Equals("非正常开机"))
                {
                    listExcepPowerOn.Add(Convert.ToInt32(listViewShow.Items[i].SubItems[5].Text));
                }
                else if (listViewShow.Items[i].SubItems[4].Text.Equals("非正常关机"))
                {
                    listExcepPowerDown.Add(Convert.ToInt32(listViewShow.Items[i].SubItems[5].Text));
                }
            }

            lbPowerOn.Text = "非正常开机次数：" + listExcepPowerOn.Count.ToString();
            lbPowerDown.Text = "非正常关机次数：" + listExcepPowerDown.Count.ToString();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            WriteListRecordsToFile();
        }

        private void MenuFromFile_Click(object sender, EventArgs e)
        {
            ShowDataListToListView(listStructOfFile);
            menuFromEventLog.Checked = menuTotal.Checked = toolStripButtonFromEventLog.Checked = toolStripButtonTotal.Checked = false;
        }

        private void MenuFromEventLog_Click(object sender, EventArgs e)
        {
            ShowDataListToListView(listStructOfListView);
            menuFromFile.Checked = menuTotal.Checked = toolStripButtonFromFile.Checked = toolStripButtonTotal.Checked = false;
        }

        private void MenuTotal_Click(object sender, EventArgs e)
        {
            ShowDataListToListView(listStructOfWriteToFile);
            menuFromFile.Checked = menuFromEventLog.Checked = toolStripButtonFromFile.Checked = toolStripButtonFromEventLog.Checked = false;
        }

        private void MenuAbout_Click(object sender, EventArgs e)
        {
            string str = "软件名称 日志查看助手\n作    者 Window Assitant \n版    本 V1.0.1.0-200220\n编译时间 2020-02-20";
            MessageBox.Show(str, "关于", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
        }

        private void MenuVersionLog_Click(object sender, EventArgs e)
        {
            FormLog fg = new FormLog();
            fg.ShowDialog();
        }

        private void ListViewShow_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listViewShow.SelectedItems.Count > 0)
            {
                FormInput fi = new FormInput(listViewShow.SelectedItems[0].SubItems[6].Text);
                if (DialogResult.OK == fi.ShowDialog())
                {
                    listViewShow.SelectedItems[0].SubItems[6].Text = fi.strComment;
                    addCommentToList(listStructOfWriteToFile, listViewShow.SelectedItems[0], fi.strComment);
                }
            }
        }

        private void MenuOpenFile_Click(object sender, EventArgs e)
        {
            try
            {
                Process p = new Process();
                p.StartInfo.FileName = strFilePath;
                p.Start();
            }
            catch
            {
                MessageBox.Show("文件暂时不能打开！请检查此文件的位置是否正确！", "无法打开",
                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }

        private void TSMI_NextPowerOn_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonNext.Image = TSMI_NextPowerOn.Image;
            toolStripSplitButtonNext.ToolTipText = toolStripSplitButtonNext.Text = "下一个异常开机";
        }

        private void TSMI_NextPowerDown_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonNext.Image = TSMI_NextPowerDown.Image;
            toolStripSplitButtonNext.ToolTipText = toolStripSplitButtonNext.Text = "下一个异常关机";
        }

        private void TSMI_NextPowerUpDown_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonNext.Image = TSMI_NextPowerUpDown.Image;
            toolStripSplitButtonNext.ToolTipText = toolStripSplitButtonNext.Text = "下一个异常开关机";
        }

        private void TSMI_UpPowerOn_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonUp.Image = TSMI_UpPowerOn.Image;
            toolStripSplitButtonUp.ToolTipText = toolStripSplitButtonUp.Text = "上一个异常开机";

        }

        private void TSMI_UpPowerDown_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonUp.Image = TSMI_UpPowerDown.Image;
            toolStripSplitButtonUp.ToolTipText = toolStripSplitButtonUp.Text = "上一个异常关机";
        }

        private void TSMI_UpPowerUpDown_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonUp.Image = TSMI_UpPowerUpDown.Image;
            toolStripSplitButtonUp.ToolTipText = toolStripSplitButtonUp.Text = "上一个异常开关机";
        }
        private void TSSBN_ButtonClick(object sender, EventArgs e)
        {
            if (toolStripSplitButtonNext.Text.ToString().Equals("下一个异常开机"))
            {
                JumpToNext(LogConstant.JumpToDirection.PowerOn);
            }
            else if (toolStripSplitButtonNext.Text.ToString().Equals("下一个异常关机"))
            {
                JumpToNext(LogConstant.JumpToDirection.PowerDown);
            }
            else if (toolStripSplitButtonNext.Text.ToString().Equals("下一个异常开关机"))
            {
                JumpToNext(LogConstant.JumpToDirection.PowerUpAndDown);
            }
        }

        private void TSSBU_ButtonClick(object sender, EventArgs e)
        {
            if (toolStripSplitButtonUp.Text.ToString().Equals("上一个异常开机"))
            {
                JumpToUp(LogConstant.JumpToDirection.PowerOn);
            }
            else if (toolStripSplitButtonUp.Text.ToString().Equals("上一个异常关机"))
            {
                JumpToUp(LogConstant.JumpToDirection.PowerDown);
            }
            else if (toolStripSplitButtonUp.Text.ToString().Equals("上一个异常开关机"))
            {
                JumpToUp(LogConstant.JumpToDirection.PowerUpAndDown);
            }
        }


        private void button1_Click(object sender, EventArgs e)
        {
            Process proc = null;
            try
            {
                string targetDir = string.Format(@"G:\源代码\dubuyunjie-eventlogcsharp-master\eventlogcsharp\EventLogCSharp\bin\Debug\");//this is where testChange.bat lies
                proc = new Process();
                proc.StartInfo.WorkingDirectory = targetDir;
                proc.StartInfo.FileName = "SIT系统清理工具.bat";
                proc.StartInfo.Arguments = string.Format("10");//this is argument
                //proc.StartInfo.CreateNoWindow = true;
                //proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//这里设置DOS窗口不显示，经实践可行
                proc.Start();
                proc.WaitForExit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString());
            }
        }
    }
}
